
package com.cpj.signin.service;

import com.cpj.signin.entity.Message;
import com.cpj.signin.repository.MessageRepository;
import com.cpj.signin.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class SignInService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private MessageRepository messageRepository;

    private static final String SIGN_IN_KEY_PREFIX = "signin:";

    /**
     * 用户签到
     * @param userName 用户名
     * @return 签到结果，包含是否成功、连续签到天数等信息
     */
    public Map<String, Object> signIn(String userName) {
        Map<String, Object> result = new HashMap<>();
        String todayStr = DateUtils.getTodayStr();
        String monthKey = SIGN_IN_KEY_PREFIX + userName + ":" + DateUtils.getFirstDayOfMonthStr();

        System.out.println("用户签到 - userName: " + userName + ", monthKey: " + monthKey);

        // 检查今天是否已经签到
        int dayOfMonth = DateUtils.getDayOfMonth();
        Boolean isSigned = redisTemplate.opsForValue().getBit(monthKey, dayOfMonth - 1);

        System.out.println("今天是本月第 " + dayOfMonth + " 天，签到状态: " + isSigned);

        if (Boolean.TRUE.equals(isSigned)) {
            result.put("success", false);
            result.put("message", "今日已签到");
            return result;
        }

        // 执行签到
        redisTemplate.opsForValue().setBit(monthKey, dayOfMonth - 1, true);
        System.out.println("设置签到位: " + (dayOfMonth - 1) + " = true");

        // 计算连续签到天数
        int consecutiveDays = calculateConsecutiveDays(userName, dayOfMonth);
        System.out.println("连续签到天数: " + consecutiveDays);

        result.put("success", true);
        result.put("message", "签到成功");
        result.put("consecutiveDays", consecutiveDays);

        return result;
    }

    /**
     * 计算连续签到天数
     * @param userName 用户名
     * @param currentDay 当前是本月的第几天
     * @return 连续签到天数
     */
    private int calculateConsecutiveDays(String userName, int currentDay) {
        String monthKey = SIGN_IN_KEY_PREFIX + userName + ":" + DateUtils.getFirstDayOfMonthStr();
        int consecutiveDays = 0;

        // 从今天开始向前检查连续签到
        for (int i = currentDay - 1; i >= 0; i--) {
            Boolean isSigned = redisTemplate.opsForValue().getBit(monthKey, i);
            if (Boolean.TRUE.equals(isSigned)) {
                consecutiveDays++;
            } else {
                break;
            }
        }

        // 如果连续签到天数等于当前天数，说明从月初开始连续签到
        // 需要检查上个月的签到情况
        if (consecutiveDays == currentDay && currentDay > 1) {
            LocalDate lastMonth = LocalDate.now().minusMonths(1);
            String lastMonthKey = SIGN_IN_KEY_PREFIX + userName + ":" + 
                lastMonth.withDayOfMonth(1).format(java.time.format.DateTimeFormatter.ISO_LOCAL_DATE);

            int lastMonthDays = lastMonth.lengthOfMonth();
            // 检查上个月最后几天是否连续签到
            for (int i = lastMonthDays - 1; i >= 0; i--) {
                Boolean isSigned = redisTemplate.opsForValue().getBit(lastMonthKey, i);
                if (Boolean.TRUE.equals(isSigned)) {
                    consecutiveDays++;
                } else {
                    break;
                }
            }
        }

        return consecutiveDays;
    }

    /**
     * 获取用户当月签到情况
     * @param userName 用户名
     * @return 当月签到情况，包含每日签到状态和总签到天数
     */
    public Map<String, Object> getMonthlySignInStatus(String userName) {
        Map<String, Object> result = new HashMap<>();
        String monthKey = SIGN_IN_KEY_PREFIX + userName + ":" + DateUtils.getFirstDayOfMonthStr();
        int daysInMonth = DateUtils.getDaysInMonth();

        System.out.println("获取签到状态 - userName: " + userName + ", monthKey: " + monthKey + ", daysInMonth: " + daysInMonth);

        // 转换为每日签到状态
        boolean[] signInStatus = new boolean[daysInMonth];
        int signedCount = 0;

        // 逐个获取每天的签到状态
        for (int i = 0; i < daysInMonth; i++) {
            Boolean isSigned = redisTemplate.opsForValue().getBit(monthKey, i);
            signInStatus[i] = Boolean.TRUE.equals(isSigned);
            if (signInStatus[i]) {
                signedCount++;
            }
        }

        System.out.println("签到统计 - 已签到: " + signedCount + " 天");

        result.put("signInStatus", signInStatus);
        result.put("signedCount", signedCount);
        result.put("daysInMonth", daysInMonth);

        return result;
    }

    /**
     * 添加留言
     * @param userName 用户名
     * @param content 留言内容
     * @return 添加的留言
     */
    public Message addMessage(String userName, String content) {
        Message message = new Message(userName, content);
        return messageRepository.save(message);
    }

    /**
     * 获取用户的所有留言
     * @param userName 用户名
     * @return 留言列表，按创建时间倒序
     */
    public List<Message> getUserMessages(String userName) {
        return messageRepository.findByUserNameOrderByCreateTimeDesc(userName);
    }
}
